﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Modbus.Device;
using Modbus.Extensions.Enron;
using Modbus.Message;

namespace modbusEx
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Init();      
            serialPort=new SerialPort();
            master = ModbusSerialMaster.CreateRtu(serialPort);
            Timer timer = new Timer();
            timer.Interval = 100;
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (serialPort.IsOpen)
            {
                 ReciveData();
            }
            
        }

        public void Init()
        {
            this.SerialPortList.Items.Add("COM1");
            this.SerialPortList.Items.Add("COM2");
            this.SerialPortList.Items.Add("COM3");
            this.SerialPortList.Items.Add("COM4");
            this.SerialPortList.SelectedIndex = 0;
            this.BaudList.Items.Add(4800);
            this.BaudList.Items.Add(9600);
            this.BaudList.Items.Add(19200);
            this.BaudList.Items.Add(115200);
            this.BaudList.SelectedIndex = 1;
            this.ParityList.Items.Add("NONE");
            this.ParityList.Items.Add("EVEN");
            this.ParityList.Items.Add("ODD");
            this.ParityList.SelectedIndex = 0;
            this.DataBits.Items.Add(6);
            this.DataBits.Items.Add(7);
            this.DataBits.Items.Add(8);
            this.DataBits.SelectedIndex = 2;
            this.StopBits.Items.Add(1);
            this.StopBits.Items.Add(2);
            this.StopBits.SelectedIndex = 0;
            this.Options.Items.Add("01 Coil Status (0x)");
            this.Options.Items.Add("02 Input Status (1x)");
            this.Options.Items.Add("03 Holding Register (4x)");
            this.Options.Items.Add("04 Input Register (3x)");
            this.Options.SelectedIndex = 1;
            this.SlaveID.Value = 1;
            this.Count.Value = 8;
        }
        public SerialPort serialPort { get;set; }
        public ModbusMaster master;
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.btnOpen.Text == "打开串口")
            {   
                serialPort.Open();
                this.btnOpen.Text = "关闭串口";
                this.Status.BackColor = Color.Green;
            }
             else {  serialPort.Close(); this.btnOpen.Text = "打开串口";  this.Status.BackColor = Color.Red;
            }
         
        }
        //发送数据
        private void button2_Click(object sender, EventArgs e)
        {   
            if(serialPort.IsOpen) {
                if (this.Send.Text.Length > 0)
                {
                    if(this.Options.SelectedItem.ToString()=="01 Coil Status (0x)")
                    {  
                        if(this.Send.Text.Trim()=="true" || this.Send.Text.Trim() == "false")
                        {
                                
                                 master.WriteSingleCoil((byte)this.SlaveID.Value,(byte)this.StartAddress.Value, bool.Parse(this.Send.Text.Trim()));
                                 MessageBox.Show("发送成功！");
                                 WriteSingleCoilRequestResponse writeSingleCoilRequestResponse = new WriteSingleCoilRequestResponse((byte)this.SlaveID.Value,(byte)this.StartAddress.Value, bool.Parse(this.Send.Text.Trim()));
                                 this.Sendmessage.Text = writeSingleCoilRequestResponse.ToString();
                               
                        }
                        else
                        {
                            MessageBox.Show("请输入ture或者false");
                        }

                    }
                    else if(this.Options.SelectedItem.ToString()=="02 Input Status (1x)")
                    {
                        MessageBox.Show("该模式只能读取！");
                    }
                     else if(this.Options.SelectedItem.ToString()=="03 Holding Register (4x)")
                    {
                        ushort data = ushort.Parse(this.Send.Text.Trim());
                         master.WriteSingleRegister((byte)this.SlaveID.Value, (ushort)this.StartAddress.Value,data );
                         MessageBox.Show("发送成功！");
                    }
                       else if(this.Options.SelectedItem.ToString()=="04 Input Register (3x)")
                    {
                        MessageBox.Show("该模式只能读取！");
                    }
                }
                else MessageBox.Show("发送数据不能为空！");
                
            }
            else { MessageBox.Show("串口未打开！"); };
        }
        //接收数据
        public void ReciveData()
        {
            if(this.Options.SelectedItem.ToString()=="01 Coil Status (0x)" || this.Options.SelectedItem.ToString()=="02 Input Status (1x)")
            {   
                bool[] data =new bool[(int)this.Count.Value];
                if(this.Count.Value > 0)
                {
                    data = master.ReadCoils((byte)this.SlaveID.Value,(ushort)this.StartAddress.Value, (ushort)this.Count.Value );
                    this.Recive.Text=string.Join(" ",data); 
                }
               
                ReadCoilsInputsRequest readCoilsReq = new ReadCoilsInputsRequest(0x01,(byte)this.SlaveID.Value,(ushort)this.StartAddress.Value, (ushort)this.Count.Value);   
                var readCoilsRes = master.ExecuteCustomMessage<ReadCoilsInputsResponse>(readCoilsReq);
                this.Recivemessage.Text = readCoilsReq.ToString();
            }
            else if(this.Options.SelectedItem.ToString()=="03 Holding Register (4x)" || this.Options.SelectedItem.ToString()=="04 Input Register (3x)") 
            {

                if (this.Count.Value > 0)
                {
                    var data = master.ReadHoldingRegisters((byte)this.SlaveID.Value,(ushort)this.StartAddress.Value, (ushort)this.Count.Value);
                    this.Recive.Text = string.Join(" ", data);
                }
            }

        }
        //设置串口对象
        public void CreateSingle()
        {
                serialPort.PortName=this.SerialPortList.SelectedItem.ToString();
                serialPort.BaudRate= (int)this.BaudList.SelectedItem;
            switch (this.ParityList.SelectedItem.ToString())
            {
                case "NONE":
                    serialPort.Parity=Parity.None;
                    break;
                 case "EVEN":
                    serialPort.Parity=Parity.Even;
                    break;
                 case "ODD":
                    serialPort.Parity=Parity.Odd;
                    break;

            }
               
                serialPort.DataBits= (int)this.DataBits.SelectedItem;
                serialPort.StopBits= (StopBits)this.StopBits.SelectedItem;
        }
        //清空数据
        private void button1_Click_1(object sender, EventArgs e)
        {
            this.Send.Text = string.Empty;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Recive.Text = string.Empty;
        }

    }
}
